#include "MyHandler.h"
#include "socketinclude.h"

#include <sys/stat.h>
#include <io.h>
#include <fcntl.h>

MyHandler::MyHandler(const int connfd)
    :_connfd(connfd)
{
    _isClosed = false;
}

MyHandler::~MyHandler()
{
    if(!_isClosed)
        closesocket(_connfd);
}

void MyHandler::handle()
{
    if(!receiveRequest())
    {
        closesocket(_connfd);
        _isClosed = true;
        return;
    }
    if(_request.method != "GET")
    {
        sendErrorMsg("501", "Not Implemented",
                     "Server doesn't implement this method");
        return;
    }

    parseURI();
    struct stat fileInfo;

    if(stat(_fileName.c_str(), &fileInfo) < 0)
    {
        std::cout << "404 Not found: Server couldn't find this file." << std::endl;
        sendErrorMsg("404", "Not Found", "Server couldn't find this file");
        return;
    }

    //    if(!(S_ISREG(fileInfo.st_mode)) || !(S_IRUSR & fileInfo.st_mode))
    //    {
    //        std::cout << "403 Forbidden: Server couldn't read this file." << std::endl;
    //        sendErrorMsg("403", "Forbidden", "Server couldn't read this file");
    //        return;
    //    }

    getFileType();
    std::string msg = "HTTP/1.1 200 OK\r\n";
    msg += "Server: Tiny Web Server\r\n";
    //msg += "Content-length: " + std::to_string(fileInfo.st_size) + "\r\n";
    msg += "Content_type: " + _fileType + "\r\n\r\n";
    _outputBuffer.append(msg.c_str(), msg.size());

    FILE* fp_file = NULL;

    std::cout <<  "---------  " <<_fileName<<std::endl;
    std::cout <<  "---------  " <<msg<<std::endl;
    fp_file = fopen(_fileName.c_str(),"rt");
    assert(fp_file != NULL);

    _outputBuffer.readFileFd(fp_file);

    std::cout <<  "-----_connfd----  " <<_connfd<<std::endl;
    _outputBuffer.sendFd(_connfd);

#if defined(WIN32)
    closesocket(_connfd);
#else
    close(_connfd);
#endif

    fclose(fp_file);
    fp_file = NULL;

    _isClosed = true;

}


bool MyHandler::receiveRequest()
{
    if(_inputBuffer.readSocketFd(_connfd) == 0)
    {
        return false;
    }

    std::string request = _inputBuffer.readAllAsString();

    std::cout << "---------------------------Request---------------------------" << std::endl;
    std::cout << request << std::endl;
    std::cout << "-------------------------------------------------------------" << std::endl;
    Parser p(request);
    _request = p.getParseResult();
    return true;
}
void MyHandler::sendResponse()
{

}

const char *DEFAULT_ERROR_404 = "HTTP/1.1 404 Not Found\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE html><html><head><title>404 Not Found</title></head><body><h1>Not Found</h1>The requested URL was not found on this server.</body></html>";

void MyHandler::sendErrorMsg(const std::string &errorNum,
                             const std::string &shortMsg,
                             const std::string &longMsg)
{
    std::string msg = "HTTP /1.0 " + errorNum + " " + shortMsg + "\r\n";
    msg += "Content-type: text/html\r\n\r\n";
    msg += "<html><title>Error</title>";
    msg += "<body bgcolor=""ffffff"">";
    msg += errorNum + ": " + shortMsg;
    msg += "<p>" + longMsg + ": " + _fileName;
    msg += "<hr><em>The Tiny Web server</em>";
    msg += "</body></html>";

    std::cout << msg <<std::endl;
    _outputBuffer.append(msg.c_str(), msg.size());
    //_outputBuffer.append(DEFAULT_ERROR_404, strlen(DEFAULT_ERROR_404));
    _outputBuffer.sendFd(_connfd);

#if defined(WIN32)
    closesocket(_connfd);
#else
    close(_connfd);
#endif
    _isClosed = true;

}
void MyHandler::parseURI()
{
    _fileName = ".";


    if(_request.uri == "/")
    {
        _fileName += "/default.html";
    }
    else
    {
         size_t pos = _request.uri.find(".js?");
         if(pos != std::string::npos)
         {
             std::string tmp(_request.uri, 0, pos + 3);
             _fileName +=tmp;
         }
         else
         {
             _fileName +=_request.uri;
         }
    }
     std::cout << "+++++++ " << _fileName <<std::endl;
}
void MyHandler::getFileType()
{
    const char *name = _fileName.c_str();
    if(strstr(name, ".html"))
    {
        _fileType = "text/html";
    }
    else if(strstr(name, ".pdf"))
    {
        _fileType = "application/pdf";
    }
    else if(strstr(name, ".js"))
    {
        _fileType = "application/javascript";
    }
    else if(strstr(name, ".swf"))
    {
        _fileType = "application/x-shockwave-flash";
    }
    else if(strstr(name, ".png"))
    {
        _fileType = "image/png";
    }
    else if(strstr(name, ".gif"))
    {
        _fileType = "image/gif";
    }
    else if(strstr(name, ".jpg"))
    {
        _fileType = "image/jpg";
    }
    else if(strstr(name, ".jpeg"))
    {
        _fileType = "image/jpeg";
    }
    else if(strstr(name, ".css"))
    {
        _fileType = "test/css";
    }
    else
    {
        _fileType = "text/plain";
    }
}
